package com.gitee.wsl.doc.prosemirror.state.ext

import com.gitee.wsl.doc.prosemirror.model.content.ContentMatch
import com.gitee.wsl.doc.prosemirror.model.content.ResolvedPos
import com.gitee.wsl.doc.prosemirror.model.fragment.Fragment
import com.gitee.wsl.doc.prosemirror.model.fragment.Slice
import com.gitee.wsl.doc.prosemirror.model.node.NodeType
import com.gitee.wsl.doc.prosemirror.model.node.ext.canJoin
import com.gitee.wsl.doc.prosemirror.state.CommandDispatch
import com.gitee.wsl.doc.prosemirror.state.EditorState
import com.gitee.wsl.doc.prosemirror.state.Transaction
import com.gitee.wsl.doc.prosemirror.transform.ext.join
import com.gitee.wsl.doc.prosemirror.transform.ext.step
import com.gitee.wsl.doc.prosemirror.transform.step.ReplaceAroundStep


/**
删除编辑器中的屏障节点
@param state 当前编辑器状态对象
@param cut 已解析的位置信息对象
@param dispatch 事务处理回调函数，可选参数
@param dir 操作方向（当前未使用，保留参数）
@return 操作是否成功执行
 */
fun EditorState.deleteBarrier(
    cut: ResolvedPos,
    dispatch: CommandDispatch? = null,
    dir: Int,
): Boolean {
    val state = this
    val before = cut.nodeBefore!!
    val after = cut.nodeAfter!!
    var conn: List<NodeType>?=null
    var match: ContentMatch?=null
    val isolated = before.type.spec.isolating == true || after.type.spec.isolating == true

// 尝试合并非隔离节点 if (!isolated && joinMaybeClear(state, cut, dispatch)) { return true }

    val canDelAfter = !isolated && cut.parent.canReplace(cut.index(), cut.index() + 1)
    if (canDelAfter && (
                before.contentMatchAt(before.childCount)
                    .apply { match = this }
                    .findWrapping(after.type)
                    .apply { conn = this }
                )?.isNotEmpty() == true
        && match?.matchType(conn?.firstOrNull() ?: after.type)?.validEnd == true
    ) {
        if (dispatch != null) {
            val end = cut.pos + after.nodeSize
            var wrap = Fragment.empty
            for (i in conn!!.size - 1 downTo 0) {
                wrap = Fragment.from(conn[i].create(null, wrap))
            }
            wrap = Fragment . from (before.copy(wrap))

            val tr =
                state.tr.step(ReplaceAroundStep(cut.pos - 1, end, cut.pos, end, Slice(wrap, 1, 0), conn.size, true))
            val joinAt = tr.doc.resolve(end + 2 * conn.size)
            if (joinAt.nodeAfter != null
                && joinAt.nodeAfter!!.type == before.type
                && tr.doc.canJoin( joinAt.pos)
            ) {
                tr.join(joinAt.pos)
            }
            dispatch (tr.scrollIntoView())
        }
        return true
    }
    return false
}